<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">

    <title>JS打字小游戏</title>
    <style>
        body {
            padding: 0;
            margin: 0;
        }

        #gameStage {
            width: 100%;
            height: 1000px;
            background-color: aquamarine;

        }
        #border span{
            color: white;
            font-size: 64px;
           // z-index:100;
        }
        #border{
            position: absolute;
            margin: 20px 20px;
            width: 300px;
            background-color: darkslategrey;
            border-radius: 8px;
            z-index:99;
            opacity:0.85;  /*透明度85%*/

            text-align:center;
        }

        #info{
            position:absolute;                       //绝对定位
            top:50%;                                   //距顶部50%
            left:50%;
          //  background-color: darkslategrey;

            color : white;
            fontSize : 300px;


            z-index:100;
          //  opacity:0.85;  /*透明度85%*/

            text-align:center;
        }
    </style>
</head>
<body>
<div id="gameStage">
    <div id="border">
        <span>得分</span>
        <br/>
        <span id="score">0</span>
        <div id="info"></div>
    </div>
</div>





<script>
  /**
   * 字母
   * @param id
   * @param alphabet
   * @param posX
   * @param posY
   * @param size
   * @constructor
   */
  function Word(id, alphabet, posX, posY, size) {

    //初始化数据
    this.id = id || '';
    this.alphabet = alphabet || 'a';
    this.posX = posX || 0;
    this.posY = posY || 0;
    this.size = size || 64;


    // 新建
    this.create = function () {
      var str = '<span class="word" id="alphabet-' + this.id + '">' + this.alphabet + '</span>';
      var gameStage = document.getElementById('gameStage');
      gameStage.innerHTML += str;

      var divNode = document.getElementById('alphabet-' + this.id);
      divNode.style.position = 'absolute';
      divNode.style.fontSize = this.size + 'px';
      divNode.style.left = this.posX + 'px';
      divNode.style.top = this.posY + 'px';

    };

    // 重置.
    this.reset = function () {
      var divNode = document.getElementById('alphabet-' + this.id);
      divNode.style.display = 'none';
      this.moveTo(0, 0);
    };

    // 移动到指定点
    this.moveTo = function (posX, posY) {
      this.posX = posX;
      this.posY = posY;

      var divNode = document.getElementById('alphabet-' + this.id);
      divNode.style.left = posX + 'px';
      divNode.style.top = posY + 'px';
    };

  }

  /**
   * 导演类
   */
  var director = {
    alphabets: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
                                    'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'],

    nodes: new Array(),

    /**
     * 逐帧运行
     */
    runFrame: function () {

      //更新已经产生所有点的坐标
      for (var index in this.nodes) {
        var node = this.nodes[index];
        if (node) {
          node.moveTo(node.posX, node.posY + 10);
        }
        if(node&&node.posY>window.innerHeight-60){
            gameOver();                                                 //显示最终得分
            location.reload();                                          //刷新页面
        }
      }

      //随机产生字母
      var r = Math.floor(Math.random() * this.alphabets.length);
      var w = new Word(new Date().getTime(), this.alphabets[r]);

      w.create();
      this.nodes.push(w);

      var posX = Math.floor(Math.random() * window.innerWidth);
      if (posX < 50) {
        posX = 100;
      }
      if (posX >= window.innerWidth - 100) {
        posX = window.innerWidth - 100;                         //防止字母显示在屏幕外
      }

      w.moveTo(posX, 0);


    },

    /**
     * 开始游戏
     */
    start: function () {
      var _this = this;
                                                   //标志位，判断是否找到
      //监听键盘事件
      document.onkeydown = function () {
          var flag = false;
          var alphabet = String.fromCharCode(event.keyCode); //获取键盘敲中的字母
        for (var i = 0, len = _this.nodes.length; i < len; i++) {
          if(!_this.nodes[i]) {
            continue;
          }
          if (alphabet === _this.nodes[i].alphabet) {
            _this.nodes[i].reset();
            scoreCounter.incScore();
            disScore.info();
            _this.nodes[i] = null;
            console.log(scoreCounter.getScore());
            flag = true;
          }
            disScore.myFunction();
        }
          if(!flag) {
              scoreCounter.decScore();
              disScore.myFunction();
              scoreCounter.errScore();

           //   disScore.info();
          }

      };

      //游戏主循环
      setInterval(function () {
        _this.runFrame();
      }, 300);

    }

  }

  /**
   * 计分器
   */
  var scoreCounter = {
      score : 0,
      errorScore : 0,
    incScore: function () {
      this.score++;
    },
      decScore: function () {
          this.score--;
      },
    getScore: function () {
      return this.score;
    },
    errScore:function () {
        this.errorScore++;
    },
    getErrorScore:function () {
        return this.errorScore;
    }
  };

    /**
    *显示实时得分
    **/
  var  disScore =
  {
      myFunction : function () {

          var div = document.getElementById("score");    //document指文档本身
          div.style.color = 'white';
          div.style.fontSize = '64px';

          document.getElementById("score").innerHTML = scoreCounter.getScore();         //实时显示得分
      },
      info: function () {

          setTimeout(function(){document.getElementById("info").innerHTML = "+1";}, 5000);

      }
  }

  /**
    *显示游戏结束提示
   **/

  function gameOver(){
      if (scoreCounter.getScore() <= 0){
          alert("               挑战失败！你的最终得分："+scoreCounter.getScore()+" 分。\n"+"               你总共按错了 "+scoreCounter.getErrorScore()+" 个字母。"
                        +"\n\n点击【确定】重新开始游戏。");

      }
      else if(scoreCounter.getScore() > 0 && scoreCounter.getScore() < 50){
          alert("               厉害了我的哥！你的最终得分："+scoreCounter.getScore()+" 分。\n"+"               你总共按错了 "+scoreCounter.getErrorScore()+" 个字母。"
                        +"\n\n点击【确定】重新开始游戏。");
      }
      else if(scoreCounter.getScore() >= 50){
          alert("               超神了！你的最终得分："+scoreCounter.getScore()+" 分。\n"+"              你总共按错了 "+scoreCounter.getErrorScore()+" 个字母。"
                        +"\n\n点击【确定】重新开始游戏。");
      }
      else{
          alert("               游戏结束！你的最终得分："+scoreCounter.getScore()+" 分。\n"+"             你总共按错了 "+scoreCounter.getErrorScore()+" 个字母。"
                        +"\n\n点击【确定】重新开始游戏。");
      }
  }

  director.start();

</script>
</body>

</html>